package com.gitee.wsl.android.ui.recyclerView.adapter

import android.util.SparseArray
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gitee.wsl.android.ui.recyclerView.adapter.viewholder.VIEW_HOLDER_TYPE_EMPTY
import com.gitee.wsl.android.ui.recyclerView.adapter.viewholder.EmptyViewHolder
import com.gitee.wsl.android.ui.recyclerView.adapter.viewholder.Subscriber
import com.gitee.wsl.ext.base.isTrue
import java.lang.ref.WeakReference

@Suppress("UNCHECKED_CAST")
abstract class BaseBuilderAdapter<T:Any,AR: com.gitee.wsl.android.ui.recyclerView.adapter.ActionRepository<T>>(mWrappedAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>,
                                                                                                               val adapterConfig: AdapterConfig<T,AR>) :WrapAdapter(mWrappedAdapter) {

    private val defaultViewHolderFactoryCache=adapterConfig.viewHolderFactoryCache

    private val sparseArrayLayoutInflater = SparseArray<WeakReference<LayoutInflater>>(1)

    init {
        if(getRepository()!=null && adapterConfig.repository==null)
            adapterConfig.repository=getRepository()
        adapterConfig.itemFlagManger?.apply {
            init { getItem( it) }
            registerAdapterDataObserver(observer)
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if(viewType==VIEW_HOLDER_TYPE_EMPTY) return EmptyViewHolder(parent)
        return defaultViewHolderFactoryCache[viewType].getViewHolder(
            parent, sparseArrayLayoutInflater.get(0).get() ?: LayoutInflater.from(parent.context)
        )
    }

    override fun onBindViewHolder(
        holder: RecyclerView.ViewHolder,
        position: Int,
        payloads: List<Any>
    ) {
        if (position != RecyclerView.NO_POSITION) {
           if (holder is Subscriber<*,*>) {
               holder as Subscriber<T,AR>

               holder.onBindViewHolder(position, payloads, getItem(position),adapterConfig )
           }
        }
    }

    fun getRepository():AR?=null

    override fun getItemViewType(position: Int): Int {
        var pre:T?=null
        var next:T?=null
        (position>0).isTrue { pre=getItem(position-1) }
        (position<itemCount).isTrue { next=getItem(position+1) }

        return adapterConfig.itemTypeCallBack?.let { it(position,getItem(position),pre,next,layoutType) }?:VIEW_HOLDER_TYPE_EMPTY
    }

    abstract fun getItem(position: Int):T?


    override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
        if (holder is Subscriber<*,*>) {
            holder.unBindViewHolder(holder.absoluteAdapterPosition)
        }
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        sparseArrayLayoutInflater.append(0, WeakReference(LayoutInflater.from(recyclerView.context)))
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        defaultViewHolderFactoryCache.clear()
        sparseArrayLayoutInflater.clear()
    }

     override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
        if (holder is Subscriber<*,*>) {
            holder.onViewAttachedToWindow(holder, holder.absoluteAdapterPosition)
        }
    }

     override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
        if (holder is Subscriber<*,*>) {
            holder.onViewDetachedFromWindow(holder, holder.absoluteAdapterPosition)
        }
    }
}